package com.finance.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.finance.entity.ScreeningDetail;
import com.finance.mapper.ScreeningDetailMapper;
import com.finance.service.ScreeningDetailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * C18
 * 场次放映明细数据Service实现类
 */
@Slf4j
@Service
public class ScreeningDetailServiceImpl extends ServiceImpl<ScreeningDetailMapper, ScreeningDetail> implements ScreeningDetailService {

    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int processOrders(List<Map<String, String>> records) {
        return processOrders(records, null, false, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int processOrders(List<Map<String, String>> records, String searchDate, boolean forceUpdate, String cinemaId) {
        if (records == null || records.isEmpty()) {
            return 0;
        }

        // 如果强制更新，先删除指定日期和影院ID的数据
        if (forceUpdate) {
            LambdaQueryWrapper<ScreeningDetail> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ScreeningDetail::getSearchDate, searchDate)
                  .eq(ScreeningDetail::getCinemaId, cinemaId);
            this.remove(wrapper);
        }

        List<ScreeningDetail> screenings = new ArrayList<>();
        for (Map<String, String> record : records) {
            try {
                ScreeningDetail screening = new ScreeningDetail();
                screening.setCinemaId(cinemaId);
                //影院,影片名称,影片别名,影片产地,影厅,影厅类型,放映日期,放映时间,场次数
                if (StringUtils.hasText(record.get("影院"))) {
                    screening.setCinema(record.get("影院"));
                }
                if (StringUtils.hasText(record.get("影片名称"))) {
                    screening.setMovieName(record.get("影片名称"));
                }
                if (StringUtils.hasText(record.get("影片别名"))) {
                    screening.setMovieAlias(record.get("影片别名"));
                }
                if (StringUtils.hasText(record.get("影片产地"))) {
                    screening.setMovieOrigin(record.get("影片产地"));
                }
                if (StringUtils.hasText(record.get("影厅"))) {
                    screening.setHall(record.get("影厅"));
                }
                if (StringUtils.hasText(record.get("影厅类型"))) {
                    screening.setHallType(record.get("影厅类型"));
                }
                String screeningDateStr = record.get("放映日期");
                if (StringUtils.hasText(screeningDateStr)) {
                    screening.setScreeningDate(LocalDate.parse(screeningDateStr, DATE_FORMATTER));
                }
                String screeningTimeStr = record.get("放映时间");
                if (StringUtils.hasText(screeningTimeStr)) {
                    screening.setScreeningTime(LocalTime.parse(screeningTimeStr, TIME_FORMATTER));
                }
                String screeningCountStr = record.get("场次数");
                if (StringUtils.hasText(screeningCountStr)) {
                    screening.setScreeningCount(Integer.parseInt(screeningCountStr));
                }
                // 票房总金额,观影总人数,平均票价,服务费总金额,网络代售费
                String totalBoxOfficeStr = record.get("票房总金额");
                if (StringUtils.hasText(totalBoxOfficeStr)) {
                    screening.setTotalBoxOffice(new BigDecimal(totalBoxOfficeStr));
                }
                String totalAudienceStr = record.get("观影总人数");
                if (StringUtils.hasText(totalAudienceStr)) {
                    screening.setTotalAudience(Integer.parseInt(totalAudienceStr));
                }
                String averageTicketPriceStr = record.get("平均票价");
                if (StringUtils.hasText(averageTicketPriceStr)) {
                    screening.setAverageTicketPrice(new BigDecimal(averageTicketPriceStr));
                }
                String totalServiceFeeStr = record.get("服务费总金额");
                if (StringUtils.hasText(totalServiceFeeStr)) {
                    screening.setTotalServiceFee(new BigDecimal(totalServiceFeeStr));
                }
                String onlineSaleFeeStr = record.get("网络代售费");
                if (StringUtils.hasText(onlineSaleFeeStr)) {
                    screening.setOnlineSaleFee(new BigDecimal(onlineSaleFeeStr));
                }
                // 场次总收入,本地销售票房金额,本地销售票数,本地退票金额,本地退票票数
                String totalIncomeStr = record.get("场次总收入");
                if (StringUtils.hasText(totalIncomeStr)) {
                    screening.setTotalIncome(new BigDecimal(totalIncomeStr));
                }
                String localSaleBoxOfficeStr = record.get("本地销售票房金额");
                if (StringUtils.hasText(localSaleBoxOfficeStr)) {
                    screening.setLocalSaleBoxOffice(new BigDecimal(localSaleBoxOfficeStr));
                }
                String localSaleTicketsStr = record.get("本地销售票数");
                if (StringUtils.hasText(localSaleTicketsStr)) {
                    screening.setLocalSaleTickets(Integer.parseInt(localSaleTicketsStr));
                }
                String localRefundAmountStr = record.get("本地退票金额");
                if (StringUtils.hasText(localRefundAmountStr)) {
                    screening.setLocalRefundAmount(new BigDecimal(localRefundAmountStr));
                }
                String localRefundTicketsStr = record.get("本地退票票数");
                if (StringUtils.hasText(localRefundTicketsStr)) {
                    screening.setLocalRefundTickets(Integer.parseInt(localRefundTicketsStr));
                }
                // 网上售票票房金额,网上销售票数,网上退票金额,网上退票票数,退票总数量
                String onlineSaleBoxOfficeStr = record.get("网上售票票房金额");
                if (StringUtils.hasText(onlineSaleBoxOfficeStr)) {
                    screening.setOnlineSaleBoxOffice(new BigDecimal(onlineSaleBoxOfficeStr));
                }
                String onlineSaleTicketsStr = record.get("网上销售票数");
                if (StringUtils.hasText(onlineSaleTicketsStr)) {
                    screening.setOnlineSaleTickets(Integer.parseInt(onlineSaleTicketsStr));
                }
                String onlineRefundAmountStr = record.get("网上退票金额");
                if (StringUtils.hasText(onlineRefundAmountStr)) {
                    screening.setOnlineRefundAmount(new BigDecimal(onlineRefundAmountStr));
                }
                String onlineRefundTicketsStr = record.get("网上退票票数");
                if (StringUtils.hasText(onlineRefundTicketsStr)) {
                    screening.setOnlineRefundTickets(Integer.parseInt(onlineRefundTicketsStr));
                }
                String totalRefundTicketsStr = record.get("退票总数量");
                if (StringUtils.hasText(totalRefundTicketsStr)) {
                    screening.setTotalRefundTickets(Integer.parseInt(totalRefundTicketsStr));
                }
                // 退票总金额,补登数量,补登金额,排映座位数,上座率
                String totalRefundAmountStr = record.get("退票总金额");
                if (StringUtils.hasText(totalRefundAmountStr)) {
                    screening.setTotalRefundAmount(new BigDecimal(totalRefundAmountStr));
                }
                String supplementCountStr = record.get("补登数量");
                if (StringUtils.hasText(supplementCountStr)) {
                    screening.setSupplementCount(Integer.parseInt(supplementCountStr));
                }
                String supplementAmountStr = record.get("补登金额");
                if (StringUtils.hasText(supplementAmountStr)) {
                    screening.setSupplementAmount(new BigDecimal(supplementAmountStr));
                }
                String totalSeatsStr = record.get("排映座位数");
                if (StringUtils.hasText(totalSeatsStr)) {
                    screening.setTotalSeats(Integer.parseInt(totalSeatsStr));
                }
                String occupancyRateStr = record.get("上座率");
                if (StringUtils.hasText(occupancyRateStr)) {
                    screening.setOccupancyRate(new BigDecimal(occupancyRateStr));
                }
                // 影片编码,语言,影片版本,场次号,影院国家编码,影院所属区域,其它费用,影厅专资编码,影片时长（分钟）
                if (StringUtils.hasText(record.get("影片编码"))) {
                    screening.setMovieCode(record.get("影片编码"));
                }
                if (StringUtils.hasText(record.get("语言"))) {
                    screening.setLanguage(record.get("语言"));
                }
                if (StringUtils.hasText(record.get("影片版本"))) {
                    screening.setMovieVersion(record.get("影片版本"));
                }
                if (StringUtils.hasText(record.get("场次号"))) {
                    screening.setScreeningNo(record.get("场次号"));
                }
                if (StringUtils.hasText(record.get("影院国家编码"))) {
                    screening.setCinemaCountryCode(record.get("影院国家编码"));
                }
                if (StringUtils.hasText(record.get("影院所属区域"))) {
                    screening.setCinemaArea(record.get("影院所属区域"));
                }
                String otherFeesStr = record.get("其它费用");
                if (StringUtils.hasText(otherFeesStr)) {
                    screening.setOtherFees(new BigDecimal(otherFeesStr));
                }
                if (StringUtils.hasText(record.get("影厅专资编码"))) {
                    screening.setHallCode(record.get("影厅专资编码"));
                }
                String movieDurationStr = record.get("影片时长（分钟）");
                if (StringUtils.hasText(movieDurationStr)) {
                    screening.setMovieDuration(Integer.parseInt(movieDurationStr));
                }
                
                screening.setSearchDate(searchDate);
                
                screenings.add(screening);
            } catch (Exception e) {
                log.error("Error processing C18 record: {}", record, e);
                throw new RuntimeException("Failed to process C18 record", e);
            }
        }

        try {
            saveBatch(screenings);
            return screenings.size();
        } catch (Exception e) {
            log.error("Error saving C18 data batch", e);
            throw new RuntimeException("Failed to save C18 data batch", e);
        }
    }
} 